import requests
import pandas as pd
import json
import os


class Config:
    """
    配置类：存储API请求相关的所有配置信息
    
    属性:
        BASE_URL (str): API的基础URL地址，包含完整的接口路径
        HEADERS (dict): API请求头信息，包含认证token和其他必要的HTTP头信息
            - token: API认证令牌
            - Accept: 接受的响应类型
            - Accept-Encoding: 接受的编码方式
            - User-Agent: 客户端标识
            - Connection: 连接类型
            - Content-Type: 请求体内容类型
    """
    BASE_URL = "http://192.168.1.14:10200/yunqi/e-server-device-service/device/data"
    HEADERS = {
        "token": "yunqi",
        "Accept": "*/*",
        "Accept-Encoding": "gzip, deflate, br",
        "User-Agent": "PostmanRuntime-ApipostRuntime/1.1.0",
        "Connection": "keep-alive",
        "Content-Type": "application/json"
    }



def read_data_from_URL(deviceIds, deviceType, fieldNames, start_time, end_time):
    """
    从API获取设备数据并处理为DataFrame格式
    
    参数:
        deviceIds (str): 设备ID，例如："435"
        deviceType (str): 设备类型，例如："tem"（温度传感器）
        fieldNames (str): 需要获取的字段名称，多个字段用逗号分隔，例如："t18,t19"
        start_time (str): 数据开始时间，格式："YYYY-MM-DD HH:MM:SS"
        end_time (str): 数据结束时间，格式："YYYY-MM-DD HH:MM:SS"
    
    返回:
        pandas.DataFrame: 处理后的数据框，包含以下列：
            - timestamp: 时间戳
            - fieldNames中指定的字段值（如t18, t19等）
            - fieldNames中指定的字段的平均值（如t18_avg, t19_avg等）
    
    处理流程:
        1. 发送POST请求到API获取数据
        2. 检查API响应状态
        3. 解析JSON数据并转换为DataFrame
        4. 处理时间戳和数值类型
        5. 合并多个字段的数据
        6. 保存数据到CSV文件
    
    异常:
        如果API返回错误（code != 0），将返回None
    """
    payload = {
        "deviceIds": deviceIds,
        "deviceType": deviceType,
        "fieldNames": fieldNames,
        "startTime": start_time,
        "endTime": end_time,
    }

    response = requests.request("POST", Config.BASE_URL, json=payload, headers=Config.HEADERS)
    response_data = response.json()
    
    # 检查响应状态
    if response_data['code'] != 0:
        print(f"API返回错误: {response_data['message']}")
        return None
        
    # 提取数据
    device_data = response_data['data'][0]
    field_data = device_data['data']
    
    # 创建时间序列数据框
    dfs = []
    for field in field_data:
        field_name = field['fieldName']
        values = field['values']
        
        # 将数据转换为DataFrame
        df_field = pd.DataFrame(values)
        df_field['value'] = pd.to_numeric(df_field['value'], errors='coerce')
        df_field['avgValue'] = pd.to_numeric(df_field['avgValue'], errors='coerce')
        df_field = df_field.rename(columns={
            'ts': 'timestamp',
            'value': field_name,
            'avgValue': f'{field_name}_avg'
        })
        dfs.append(df_field)
    
    # 合并所有字段的数据
    if len(dfs) > 1:
        final_df = dfs[0]
        for df in dfs[1:]:
            final_df = pd.merge(final_df, df, on='timestamp', how='outer')
    else:
        final_df = dfs[0]
    
    # 设置时间戳为索引
    final_df['timestamp'] = pd.to_datetime(final_df['timestamp'])
    final_df = final_df.sort_values('timestamp')
    
    
    return final_df

def merge_multiple_sensor_data(sensor_configs, start_time, end_time):
    """
    合并多组传感器数据
    
    参数:
        sensor_configs (list): 传感器配置列表，每个配置是一个字典，包含：
            - deviceIds: 设备ID
            - deviceType: 设备类型
            - fieldNames: 字段名称
            - prefix: 列名前缀（可选）
        start_time (str): 数据开始时间
        end_time (str): 数据结束时间
    
    返回:
        pandas.DataFrame: 合并后的数据框，包含所有传感器的数据
    """
    # 获取第一组数据作为基准
    first_config = sensor_configs[0]
    merged_data = read_data_from_URL(
        first_config['deviceIds'],
        first_config['deviceType'],
        first_config['fieldNames'],
        start_time,
        end_time
    )
    
    # 如果配置中有前缀，添加前缀到列名
    if 'prefix' in first_config:
        prefix = first_config['prefix']
        columns_to_rename = [col for col in merged_data.columns if col != 'timestamp']
        merged_data = merged_data.rename(columns={col: f"{prefix}{col}" for col in columns_to_rename})
    
    # 依次合并其他组数据
    for config in sensor_configs[1:]:
        current_data = read_data_from_URL(
            config['deviceIds'],
            config['deviceType'],
            config['fieldNames'],
            start_time,
            end_time
        )
        
        # 如果配置中有前缀，添加前缀到列名
        if 'prefix' in config:
            prefix = config['prefix']
            columns_to_rename = [col for col in current_data.columns if col != 'timestamp']
            current_data = current_data.rename(columns={col: f"{prefix}{col}" for col in columns_to_rename})
            
        merged_data = pd.merge(merged_data, current_data, on='timestamp', how='outer')
    
    print('='*100)
    print(merged_data.head())
    print('='*100)

    # 按时间戳排序
    merged_data = merged_data.sort_values('timestamp')
    return merged_data


def aggregate_sensor_data(df, device_ids, field_name):
    """
    聚合多个传感器的数据
    
    参数:
        df: 原始数据框
        device_ids: 设备ID列表
        field_name: 字段名称
    
    返回:
        聚合后的数据框
    """
    # 对多个传感器的数据进行平均
    aggregated_data = df[field_name].mean(axis=1)
    return aggregated_data